<template>
  <div class="maintenance-plan">
    <div class="header-wrapper">
      <div class="header-title">保养计划管理</div>
      <p class="tips">
        右键点击今日及之后的日期可以添加或编辑保养计划，过去日期可查看和删除
      </p>
    </div>

    <div class="calendar-container">
      <el-calendar v-model="calendarValue" class="custom-calendar">
        <template #date-cell="{ data }">
          <div
            class="calendar-day"
            :class="{
              'has-plan': getPlanForDate(data.day),
            }"
            @contextmenu.prevent="
              !props.isLook && handleRightClick($event, data)
            "
          >
            <div class="date-number">{{ data.day.split("-").pop() }}</div>
            <div
              v-if="getPlanForDate(data.day)"
              class="plan-content"
              :title="getPlanForDate(data.day)?.planName"
            >
              {{ getPlanForDate(data.day)?.planName }}
            </div>
          </div>
        </template>
      </el-calendar>
    </div>

    <!-- 右键菜单 -->
    <div
      v-show="contextMenuVisible && !props.isLook"
      :style="{ left: contextMenuX + 'px', top: contextMenuY + 'px' }"
      class="context-menu"
      @mouseleave="hideContextMenu"
    >
      <!-- 今日及之后的日期 -->
      <template v-if="!isPastDate(selectedDate)">
        <div v-if="!selectedDatePlan" class="menu-item" @click="openAddDialog">
          <i class="el-icon-plus"></i>
          添加计划
        </div>
        <template v-else>
          <div class="menu-item" @click="openEditDialog">
            <i class="el-icon-edit"></i>
            编辑计划
          </div>
          <div class="menu-item delete-item" @click="deletePlan">
            <i class="el-icon-delete"></i>
            删除计划
          </div>
        </template>
      </template>
      <!-- 过去日期的操作 -->
      <template v-else>
        <div v-if="selectedDatePlan" class="menu-item" @click="viewPlan">
          <i class="el-icon-view"></i>
          查看计划
        </div>
        <div
          v-if="selectedDatePlan"
          class="menu-item delete-item"
          @click="deletePlan"
        >
          <i class="el-icon-delete"></i>
          删除计划
        </div>
        <div v-if="!selectedDatePlan" class="menu-item disabled-item">
          <i class="el-icon-info"></i>
          过去日期不可添加
        </div>
      </template>
    </div>

    <!-- 添加/编辑/查看计划弹框 -->
    <el-dialog
      class="self-dialog"
      :model-value="dialogVisible"
      :title="
        isEditing
          ? '编辑保养计划'
          : selectedDatePlan
          ? '查看保养计划'
          : '添加保养计划'
      "
      width="500px"
      @update:model-value="dialogVisible = $event"
      @close="resetForm"
    >
      <el-form
        ref="formRef"
        :model="planForm"
        :rules="formRules"
        label-width="80px"
      >
        <el-form-item label="日期" prop="planDate">
          <el-date-picker
            v-model="planForm.planDate"
            type="date"
            format="YYYY/MM/DD"
            value-format="x"
            placeholder="请选择日期"
            :disabledDate="isEditing ? disablePastDates : undefined"
            :disabled="!isEditing"
          />
        </el-form-item>
        <el-form-item label="计划内容" prop="content">
          <el-input
            v-model="planForm.planName"
            type="textarea"
            :rows="4"
            placeholder="请输入保养计划内容"
            maxlength="200"
            show-word-limit
            :disabled="!isEditing"
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="dialogVisible = false">关闭</el-button>
          <el-button
            v-if="isEditing"
            type="primary"
            @click="submitForm"
            :loading="submitLoading"
          >
            更新
          </el-button>
          <el-button
            v-else-if="!selectedDatePlan"
            type="primary"
            @click="submitForm"
            :loading="submitLoading"
          >
            添加
          </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, watch, defineProps } from "vue";
import { useRoute } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
import {
  getAllMaintenancePlansAPI,
  addMaintenanceContractAPI,
  deleteMaintenancePlanAPI,
  MaintenancePlanType,
  GetMaintenancePlansByDateRangeType,
  MaintenancePlanStatus,
} from "@/api/service/maintenancePlan";
import { formatDate } from "@/assets/js/utils";

const route = useRoute();
const deviceId = route.query.id as string;

const props = defineProps<{
  isLook: boolean;
}>();

// 数据定义
const calendarValue = ref(new Date());
const maintenancePlans = ref<MaintenancePlanType[]>([]);
const loading = ref(false);

// 右键菜单相关
const contextMenuVisible = ref(false);
const contextMenuX = ref(0);
const contextMenuY = ref(0);
const selectedDate = ref("");
const selectedDatePlan = ref<MaintenancePlanType | null>(null);

// 弹框相关
const dialogVisible = ref(false);
const isEditing = ref(false);
const submitLoading = ref(false);
const formRef = ref();

// 表单数据
const planForm = reactive({
  id: "",
  planName: "",
  planDate: 0,
});

// 表单验证规则
const formRules = {
  planName: [
    { required: true, message: "请输入计划内容", trigger: "blur" },
    { min: 1, max: 200, message: "内容长度在1到200个字符", trigger: "blur" },
  ],
};

// 根据日期获取计划
const getPlanForDate = (date: number): MaintenancePlanType | null => {
  return (
    maintenancePlans.value.find((plan) => {
      if (plan.planDate) {
        return formatDate(plan.planDate) === formatDate(date);
      }
      return false;
    }) || null
  );
};

// 获取日历视图中显示的第一天和最后一天
const getCalendarViewRange = (date: Date) => {
  const year = date.getFullYear();
  const month = date.getMonth();

  // 当前月份第一天
  const firstDayOfMonth = new Date(year, month, 1);

  // 获取第一天是星期几 (0=周日, 1=周一, ... 6=周六)
  const firstDayWeekday = firstDayOfMonth.getDay();

  // 计算日历视图的第一天 (以周一为一周开始)
  // 如果第一天是周日(0)，需要向前推6天；如果是周一(1)，不需要推；其他情况向前推(weekday-1)天
  const daysToSubtract = firstDayWeekday === 0 ? 6 : firstDayWeekday - 1;
  const calendarStartDate = new Date(firstDayOfMonth);
  calendarStartDate.setDate(calendarStartDate.getDate() - daysToSubtract);
  calendarStartDate.setHours(0, 0, 0, 0);

  // 日历通常显示6行7列=42天，所以最后一天是第一天+41天
  const calendarEndDate = new Date(calendarStartDate);
  calendarEndDate.setDate(calendarEndDate.getDate() + 41);
  calendarEndDate.setHours(23, 59, 59, 999);

  return {
    startDate: calendarStartDate.getTime(),
    endDate: calendarEndDate.getTime(),
  };
};

// 更新查询参数的时间范围
const updateQueryTimeRange = (date: Date) => {
  const { startDate, endDate } = getCalendarViewRange(date);
  getPlansQueryParams.value.startDate = startDate;
  getPlansQueryParams.value.endDate = endDate;
};

// 判断日期是否是过去的日期（不包括今天）
const isPastDate = (dateStr: string): boolean => {
  const today = new Date();
  today.setHours(0, 0, 0, 0); // 设置为今天开始时间

  const targetDate = new Date(dateStr);
  targetDate.setHours(0, 0, 0, 0);

  return targetDate < today;
};

// 禁用过去的日期（用于日期选择器）
const disablePastDates = (time: Date): boolean => {
  const today = new Date();
  today.setHours(0, 0, 0, 0);

  const targetDate = new Date(time);
  targetDate.setHours(0, 0, 0, 0);

  return targetDate < today;
};

// 获取保养计划列表
const getPlansQueryParams = ref<GetMaintenancePlansByDateRangeType>({
  startDate: null,
  endDate: null,
  deviceId: deviceId,
});
const getMaintenancePlanList = async () => {
  try {
    loading.value = true;
    const response = await getAllMaintenancePlansAPI({
      startDate: getPlansQueryParams.value.startDate,
      endDate: getPlansQueryParams.value.endDate,
      deviceId: getPlansQueryParams.value.deviceId,
    });
    maintenancePlans.value = response as any;
  } catch (error) {
    ElMessage.error("获取保养计划失败");
    console.error("获取保养计划错误:", error);
  } finally {
    loading.value = false;
  }
};

// 处理右键点击
const handleRightClick = (event: MouseEvent, data: any) => {
  const date = data.day;
  selectedDate.value = date;
  selectedDatePlan.value = getPlanForDate(date);

  contextMenuX.value = event.clientX;
  contextMenuY.value = event.clientY;
  contextMenuVisible.value = true;

  // 添加全局点击事件监听，点击其他地方隐藏菜单
  setTimeout(() => {
    document.addEventListener("click", hideContextMenu);
  }, 100);
};

// 隐藏右键菜单
const hideContextMenu = () => {
  contextMenuVisible.value = false;
  document.removeEventListener("click", hideContextMenu);
};

// 打开添加计划弹框
const openAddDialog = () => {
  isEditing.value = true;
  planForm.id = "";
  planForm.planName = "";
  planForm.planDate = new Date(selectedDate.value).getTime();
  dialogVisible.value = true;
  hideContextMenu();
};

// 打开编辑计划弹框
const openEditDialog = () => {
  if (!selectedDatePlan.value) return;

  isEditing.value = true;
  planForm.id = selectedDatePlan.value.id;
  planForm.planName = selectedDatePlan.value.planName;
  planForm.planDate = selectedDatePlan.value.planDate;
  dialogVisible.value = true;
  hideContextMenu();
};

// 查看计划
const viewPlan = () => {
  if (!selectedDatePlan.value) return;

  isEditing.value = false;
  planForm.id = selectedDatePlan.value.id;
  planForm.planName = selectedDatePlan.value.planName;
  planForm.planDate = selectedDatePlan.value.planDate;
  dialogVisible.value = true;
  hideContextMenu();
};

// 删除计划
const deletePlan = async () => {
  if (!selectedDatePlan.value) return;

  try {
    await ElMessageBox.confirm("确定要删除这个保养计划吗？", "删除确认", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "warning",
    });

    const response = await deleteMaintenancePlanAPI(selectedDatePlan.value.id);
    ElMessage.success("删除成功");
    await getMaintenancePlanList();
  } catch (error: any) {
    if (error !== "cancel") {
      ElMessage.error("删除失败");
      console.error("删除计划错误:", error);
    }
  } finally {
    hideContextMenu();
  }
};

// 提交表单
const submitForm = async () => {
  if (!formRef.value) return;

  try {
    const valid = await formRef.value.validate();
    if (!valid) return;

    submitLoading.value = true;
    addMaintenanceContractAPI({
      id: planForm.id,
      deviceId: deviceId,
      planDate: planForm.planDate,
      planName: planForm.planName,
      status: MaintenancePlanStatus.NOT_STARTED,
    })
      .then(() => {
        ElMessage.success(isEditing.value ? "更新成功" : "添加成功");
        dialogVisible.value = false;
        getMaintenancePlanList();
      })
      .catch(({ message }) => {
        ElMessage.error(message);
      })
      .finally(() => {
        submitLoading.value = false;
      });
  } catch (error) {
    ElMessage.error("操作失败");
    console.error("提交表单错误:", error);
  } finally {
    submitLoading.value = false;
  }
};

// 重置表单
const resetForm = () => {
  if (formRef.value) {
    formRef.value.resetFields();
  }
  planForm.id = "";
  planForm.planName = "";
  planForm.planDate = 0;
};

// 监听日历值变化，当月份改变时重新获取数据
watch(
  calendarValue,
  (newDate, oldDate) => {
    // 检查是否切换了月份
    if (
      !oldDate ||
      newDate.getFullYear() !== oldDate.getFullYear() ||
      newDate.getMonth() !== oldDate.getMonth()
    ) {
      updateQueryTimeRange(newDate);
      getMaintenancePlanList();
    }
  },
  { immediate: false }
);

// 组件挂载时获取数据
onMounted(() => {
  // 设置默认时间范围为当前月份
  updateQueryTimeRange(calendarValue.value);
  getMaintenancePlanList();
});
</script>

<style scoped lang="scss">
.maintenance-plan {
  .header-wrapper {
    display: flex;
    flex-direction: column;
    padding: 1.5rem;
    background-color: $bg-color-page;
    border-bottom: 1px solid $border-color-primary;
    .header-title {
      font-size: $font-size-page-menu;
      font-weight: 600;
      color: $text-color-regular;
      margin-bottom: 12px;
      padding-left: 12px;
      border-left: 4px solid $color_brand;
    }
    .tips {
      font-size: 1.2rem;
      color: $text-color-secondary;
    }
  }

  .calendar-container {
    width: 100%;
    margin: 1rem 0;
    background: white;
    border-radius: 8px;
    overflow: hidden;
  }
}

.custom-calendar {
  padding: 0 1.5rem;
  background-color: #fff;
  :deep(.el-calendar__header) {
    background: #fff;
    padding: 1.5rem;
    border-bottom: 1px solid $border-color-primary;

    .el-calendar__title {
      font-size: $font-size-base;
      font-weight: 600;
      color: $text-color-regular;
    }

    .el-calendar__button-group {
      .el-button {
        border: none;
        background: $bg-td-2-color;
        color: $text-color-regular;

        &:hover {
          text-decoration: underline;
        }
      }
    }
  }

  :deep(.el-calendar__body) {
    padding: 0;

    .el-calendar-table {
      .el-calendar-day {
        height: 8vh;
        min-height: 5rem;
        padding: 0;
      }
    }
  }
}

.calendar-day {
  height: 100%;
  padding: 0.2rem;
  position: relative;
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  flex-direction: column;

  &:hover {
    background: #f0f9ff;
  }

  &.has-plan {
    background: linear-gradient(135deg, #e6f7ff 0%, #bae7ff 100%);
    border-left: 4px solid $color_brand;

    &:hover {
      background: linear-gradient(135deg, #d6f7ff 0%, #91d5ff 100%);
    }
  }

  .date-number {
    font-size: $font-size-base;
    color: $text-color-regular;
    margin-bottom: 0.5rem;
  }

  .plan-content {
    flex: 1;
    font-size: $font-size-tips;
    color: $color_brand;
    padding-top: 0.2rem;
    border-radius: 4px;
    line-height: 1.4;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    word-break: break-all;
  }
}

.context-menu {
  position: fixed;
  background: #fff;
  border: 1px solid $border-color-primary;
  border-radius: 6px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
  z-index: 9999;
  min-width: 12rem;

  .menu-item {
    padding: 1rem 1.5rem;
    cursor: pointer;
    transition: background 0.3s ease;
    display: flex;
    align-items: center;
    font-size: $font-size-base;

    i {
      margin-right: 0.8rem;
      width: 1.6rem;
    }

    &:hover {
      background: #f5f7fa;
    }

    &.delete-item {
      color: #f56c6c;

      &:hover {
        background: #fef0f0;
      }
    }

    &.disabled-item {
      color: #666;
      cursor: default;

      &:hover {
        background: #f5f7fa;
      }

      i {
        color: #666;
      }
    }

    &:first-child {
      border-radius: 6px 6px 0 0;
    }

    &:last-child {
      border-radius: 0 0 6px 6px;
    }

    &:only-child {
      border-radius: 6px;
    }
  }
}
</style>
